﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;

namespace Radiation___IM
{
    public class Channel : Protected
    {
        private string m_name;
        private Hashtable m_clients;
        private string m_motd;

        public string Name
        {
            get
            {
                return m_name;
            }
        }
        
        public string Motd
        {
            get
            {
                return m_motd;
            }
            set
            {
                m_motd = value;
                dispatchMessageSystem("New Motd : " + m_motd);
            }
        }

        public ICollection Users
        {
            get
            {
                return m_clients.Values;
            }
        }

        public Channel(string name)
        {
            m_name = name;
            m_motd = "Welcome on this channel !";
            m_clients = new Hashtable();
        }

        public rvalue registerClient(Client client, bool doNotSendMessage = false)
        {
            if (!m_clients.ContainsKey(client.Key))
            {
                m_clients.Add(client.Key, client);
                client.add(this);

                if (!doNotSendMessage)
                {
                    dispatchMessageSystem(client.Nickname + " joined this channel.");
                    if (!client.Invisible)
                        dispatchMessageAPI(this.m_name + ";" + client.Nickname, client, Radiation.Common.Communication.APIMethods.CLIENT_ADD_USER);
                    Thread.Sleep(100); //two consecutive send
                    sendMotd(client);
                }

                return rvalue.CLIENT_REGISTERED;
            }
            else
                return rvalue.CLIENT_KEY_ALREADY_SET;
        }

        public void sendMotd(Client client)
        {
            MessageExecution.sendDataSystem(client, this.m_motd, this.m_name);
        }

        public rvalue unregisterClient(Client client)
        {
            if (m_clients.ContainsKey(client.Key))
            {
                m_clients.Remove(client.Key);
                client.delete(this);
                dispatchMessageSystem(client.Nickname + " left this channel.", client);
                if (!client.Invisible)
                    dispatchMessageAPI(this.m_name + ";" + client.Nickname, client, Radiation.Common.Communication.APIMethods.CLIENT_REMOVE_USER);
                return rvalue.CLIENT_UNREGISTERED;
            }
            else
                return rvalue.CLIENT_DOES_NOT_EXIST;
        }

        public void dispatchMessage(string message, Client from)
        {
            foreach (Int64 key in m_clients.Keys)
            {
                if (key != from.Key)
                    MessageExecution.sendData((Client)m_clients[key], message, m_name, from.Nickname);
            }
        }

        public void dispatchMessageAPI(string message, Client from, string command)
        {
            foreach (Int64 key in m_clients.Keys)
            {
                if (key != from.Key)
                    MessageExecution.sendDataAPI((Client)m_clients[key], message, command);
            }
        }

        public void dispatchMessageAPI(string message, string command)
        {
            foreach (Int64 key in m_clients.Keys)
            {
                MessageExecution.sendDataAPI((Client)m_clients[key], message, command);
            }
        }
        
        public void dispatchMessageSystem(string message, Client from)
        {
            foreach (Int64 key in m_clients.Keys)
            {
                if (key != from.Key)
                    MessageExecution.sendData((Client)m_clients[key], message, m_name, "system");
            }
        }

        public void dispatchMessageSystem(string message)
        {
            foreach (Int64 key in m_clients.Keys)
                MessageExecution.sendData((Client)m_clients[key], message, m_name, "system");
        }

        public Client getClient(string client_nickname)
        {
            foreach (Client client in m_clients.Values)
                if (client.Nickname == client_nickname)
                    return client;

            return null;
        }
    }
}
